home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / utilit~1 / futilsrc.zoo / fileutil / lib / orig / fsinfo.c next >
Encoding:
C/C++ Source or Header  |  1991-08-26  |  8.6 KB  |  389 lines

  1. /* fsinfo.c -- return info about mounted filesystems
  2.    Copyright (C) 1991 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <errno.h>
  21. #include "fsinfo.h"
  22.  
  23. #ifdef STDC_HEADERS
  24. #include <stdlib.h>
  25. #else
  26. extern int errno;
  27. void exit ();
  28. void free ();
  29. #endif
  30. #if defined(USG) || defined(STDC_HEADERS)
  31. #include <string.h>
  32. #else
  33. #include <strings.h>
  34. #endif
  35.  
  36. int statfs ();
  37.  
  38. int xatoi ();
  39. char *strstr ();
  40. char *xmalloc ();
  41. char *xrealloc ();
  42. char *xstrdup ();
  43. void error ();
  44.  
  45. #ifdef FS_MNTENT
  46. #include <sys/vfs.h>
  47. #include <mntent.h>
  48. #if !defined(MOUNTED) && defined(MNT_MNTTAB) /* HP-UX. */
  49. #define MOUNTED MNT_MNTTAB
  50. #endif
  51. #endif /* FS_MNTENT */
  52.  
  53. #ifdef FS_GETMNT
  54. #include <sys/param.h>
  55. #include <sys/mount.h>
  56. #include <sys/fs_types.h>
  57. int getmnt ();
  58. #endif
  59.  
  60. #ifdef FS_USG_STATFS
  61. #include <mnttab.h>
  62. #include <sys/statfs.h>
  63. #include <sys/fstyp.h>
  64. #endif
  65.  
  66. #ifdef FS_STATVFS
  67. #include <sys/statvfs.h>
  68. #include <sys/mnttab.h>
  69. #endif
  70.  
  71. #ifdef FS_STATFS
  72. #include <sys/mount.h>
  73.  
  74. char *
  75. fstype_to_string (t)
  76.      short t;
  77. {
  78.   switch (t)
  79.     {
  80.     case MOUNT_UFS:
  81.       return "ufs";
  82.     case MOUNT_NFS:
  83.       return "nfs";
  84.     case MOUNT_PC:
  85.       return "pc";
  86. #ifdef MOUNT_MFS
  87.     case MOUNT_MFS:
  88.       return "mfs";
  89. #endif
  90. #ifdef MOUNT_LO
  91.     case MOUNT_LO:
  92.       return "lo";
  93. #endif
  94. #ifdef MOUNT_TFS
  95.     case MOUNT_TFS:
  96.       return "tfs";
  97. #endif
  98. #ifdef MOUNT_TMP
  99.     case MOUNT_TMP:
  100.       return "tmp";
  101. #endif
  102.     default:
  103.       return "?";
  104.     }
  105. }
  106. #endif
  107.  
  108. /* Return a list of the currently mounted filesystems, or NULL on error.
  109.    Add each entry to the tail of the list so that they stay in order.
  110.    If NEED_FS_TYPE is nonzero, make sure the filesystem type fields in
  111.    the returned list are valid. */
  112.  
  113. struct mount_entry *
  114. read_filesystem_list (need_fs_type)
  115.      int need_fs_type;
  116. {
  117.   struct mount_entry *mount_list;
  118.   struct mount_entry *me;
  119.   struct mount_entry *mtail;
  120.  
  121.   /* Start the list off with a dummy entry. */
  122.   me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  123.   me->me_next = NULL;
  124.   mount_list = mtail = me;
  125.  
  126. #ifdef FS_MNTENT        /* 4.3BSD, SunOS, HP-UX */
  127.   {
  128.     struct mntent *mnt;
  129.     char *table = MOUNTED;    /* /etc/mtab, usually. */
  130.     FILE *fp;
  131.     char *devopt;
  132.  
  133.     fp = setmntent (table, "r");
  134.     if (fp == NULL)
  135.       return NULL;
  136.  
  137.     while ((mnt = getmntent (fp)))
  138.       {
  139.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  140.     me->me_devname = xstrdup (mnt->mnt_fsname);
  141.     me->me_mountdir = xstrdup (mnt->mnt_dir);
  142.     me->me_type = xstrdup (mnt->mnt_type);
  143.     devopt = strstr (mnt->mnt_opts, "dev=");
  144.     if (devopt)
  145.       {
  146.         if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  147.           me->me_dev = xatoi (devopt + 6);
  148.         else
  149.           me->me_dev = xatoi (devopt + 4);
  150.       }
  151.     else
  152.       me->me_dev = -1;    /* Magic; means not known yet. */
  153.     me->me_next = NULL;
  154.  
  155.     /* Add to the linked list. */
  156.     mtail->me_next = me;
  157.     mtail = me;
  158.       }
  159.  
  160.     if (endmntent (fp) == 0)
  161.       return NULL;
  162.   }
  163. #endif /* FS_MNTENT */
  164.  
  165. #ifdef FS_GETMNT        /* Ultrix */
  166.   {
  167.     int offset = 0;
  168.     int val;
  169.     struct fs_data fsd;
  170.  
  171.     while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
  172.               (char *) 0)) > 0)
  173.       {
  174.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  175.     me->me_devname = xstrdup (fsd.fd_req.devname);
  176.     me->me_mountdir = xstrdup (fsd.fd_req.path);
  177.     me->me_type = gt_names[fsd.fd_req.fstype];
  178.     me->me_dev = fsd.fd_req.dev;
  179.     me->me_next = NULL;
  180.  
  181.     /* Add to the linked list. */
  182.     mtail->me_next = me;
  183.     mtail = me;
  184.       }
  185.     if (val < 0)
  186.       return NULL;
  187.   }
  188. #endif /* FS_GETMNT */
  189.  
  190. #ifdef FS_USG_STATFS        /* SVR3.2 */
  191.   {
  192.     struct mnttab mnt;
  193.     char *table = "/etc/mnttab";
  194.     FILE *fp;
  195.  
  196.     fp = fopen (table, "r");
  197.     if (fp == NULL)
  198.       return NULL;
  199.  
  200.     while (fread (&mnt, sizeof mnt, 1, fp) > 0)
  201.       {
  202.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  203.     me->me_devname = xstrdup (mnt.mt_dev);
  204.     me->me_mountdir = xstrdup (mnt.mt_filsys);
  205.     me->me_dev = -1;    /* Magic; means not known yet. */
  206.     me->me_type = "";
  207.     if (need_fs_type)
  208.       {
  209.         struct statfs fsd;
  210.         char typebuf[FSTYPSZ];
  211.  
  212.         if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
  213.         && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
  214.           me->me_type = xstrdup (typebuf);
  215.       }
  216.     me->me_next = NULL;
  217.  
  218.     /* Add to the linked list. */
  219.     mtail->me_next = me;
  220.     mtail = me;
  221.       }
  222.  
  223.     if (fclose (fp) == EOF)
  224.       return NULL;
  225.   }
  226. #endif /* FS_USG_STATFS */
  227.  
  228. #ifdef FS_STATVFS        /* SVR4 */
  229.   {
  230.     struct mnttab mnt;
  231.     char *table = MNTTAB;
  232.     FILE *fp;
  233.     int ret;
  234.  
  235.     fp = fopen (table, "r");
  236.     if (fp == NULL)
  237.       return NULL;
  238.  
  239.     while ((ret = getmntent (fp, &mnt)) == 0)
  240.       {
  241.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  242.     me->me_devname = xstrdup (mnt.mnt_special);
  243.     me->me_mountdir = xstrdup (mnt.mnt_mountp);
  244.     me->me_type = xstrdup (mnt.mnt_fstype);
  245.     me->me_dev = -1;    /* Magic; means not known yet. */
  246.     me->me_next = NULL;
  247.  
  248.     /* Add to the linked list. */
  249.     mtail->me_next = me;
  250.     mtail = me;
  251.       }
  252.  
  253.     if (ret > 0)
  254.       return NULL;
  255.    if (fclose (fp) == EOF)
  256.       return NULL;
  257.   }
  258. #endif
  259.  
  260. #ifdef FS_STATFS        /* 4.4BSD */
  261.   {
  262.     struct statfs *fsp;
  263.     int entries;
  264.  
  265.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  266.     if (entries < 0)
  267.       return NULL;
  268.     while (entries-- > 0)
  269.       {
  270.     me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  271.     me->me_devname = xstrdup (fsp->f_mntfromname);
  272.     me->me_mountdir = xstrdup (fsp->f_mntonname);
  273.     me->me_type = fstype_to_string (fsp->f_type);
  274.     me->me_dev = -1;    /* Magic; means not known yet. */
  275.     me->me_next = NULL;
  276.  
  277.     /* Add to the linked list. */
  278.     mtail->me_next = me;
  279.     mtail = me;
  280.     fsp++;
  281.       }
  282.   }
  283. #endif /* FS_STATFS */
  284.  
  285.   /* Free the dummy head. */
  286.   me = mount_list;
  287.   mount_list = mount_list->me_next;
  288.   free (me);
  289.   return mount_list;
  290. }
  291.  
  292. /* Fill in the fields of FSP with information about space usage on
  293.    the filesystem on which PATH is a node.
  294.    Return 0 if successful, -1 if not. */
  295.  
  296. int
  297. get_fs_usage (path, fsp)
  298.      char *path;
  299.      struct fs_usage *fsp;
  300. {
  301. #ifdef FS_MNTENT
  302.   struct statfs fsd;
  303.  
  304.   if (statfs (path, &fsd) != 0)
  305.     return -1;
  306.   fsp->fsu_blocks = fsd.f_blocks;
  307.   fsp->fsu_bfree = fsd.f_bfree;
  308.   fsp->fsu_bavail = fsd.f_bavail;
  309.   fsp->fsu_files = fsd.f_files;
  310.   fsp->fsu_ffree = fsd.f_ffree;
  311. #endif /* FS_MNTENT */
  312.  
  313. #ifdef FS_USG_STATFS
  314. #define f_bavail f_bfree
  315.   struct statfs fsd;
  316.  
  317.   if (statfs (path, &fsd, sizeof fsd, 0) < 0)
  318.     return -1;
  319.   fsp->fsu_blocks = (fsd.f_blocks + 1) / 2;
  320.   fsp->fsu_bfree = (fsd.f_bfree + 1) / 2;
  321.   fsp->fsu_bavail = (fsd.f_bavail + 1) / 2;
  322.   fsp->fsu_files = fsd.f_files;
  323.   fsp->fsu_ffree = fsd.f_ffree;
  324. #endif
  325.  
  326. #ifdef FS_STATVFS
  327.   struct statvfs fsd;
  328.  
  329.   if (statvfs (path, &fsd) < 0)
  330.     return -1;
  331.   fsp->fsu_blocks = (fsd.f_blocks + 1) / (1024 / fsd.f_frsize);
  332.   fsp->fsu_bfree = (fsd.f_bfree + 1) / (1024 / fsd.f_frsize);
  333.   fsp->fsu_bavail = (fsd.f_bavail + 1) / (1024 / fsd.f_frsize);
  334.   fsp->fsu_files = fsd.f_files;
  335.   fsp->fsu_ffree = fsd.f_ffree;
  336. #endif
  337.  
  338. #ifdef FS_STATFS
  339.   struct statfs fsd;
  340.  
  341.   if (statfs (path, &fsd) < 0)
  342.     return -1;
  343.   fsp->fsu_blocks = (fsd.f_blocks + 1) / (1024 / fsd.f_fsize);
  344.   fsp->fsu_bfree = (fsd.f_bfree + 1) / (1024 / fsd.f_fsize);
  345.   fsp->fsu_bavail = (fsd.f_bavail + 1) / (1024 / fsd.f_fsize);
  346.   fsp->fsu_files = fsd.f_files;
  347.   fsp->fsu_ffree = fsd.f_ffree;
  348. #endif
  349.  
  350. #ifdef FS_GETMNT
  351.   struct fs_data fsd;
  352.  
  353.   if (statfs (path, &fsd) != 1)
  354.     return -1;
  355.   fsp->fsu_blocks = fsd.fd_req.btot;
  356.   fsp->fsu_bfree = fsd.fd_req.bfree;
  357.   fsp->fsu_bavail = fsd.fd_req.bfreen;
  358.   fsp->fsu_files = fsd.fd_req.gtot;
  359.   fsp->fsu_ffree = fsd.fd_req.gfree;
  360. #endif /* FS_GETMNT */
  361.   return 0;
  362. }
  363.  
  364. /* Return the value of the hexadecimal number represented by CP.
  365.    No prefix (like '0x') or suffix (like 'h') is expected to be
  366.    part of CP. */
  367.  
  368. int
  369. xatoi (cp)
  370.      char *cp;
  371. {
  372.   int val;
  373.   
  374.   val = 0;
  375.   while (*cp)
  376.     {
  377.       if (*cp >= 'a' && *cp <= 'f')
  378.     val = val * 16 + *cp - 'a' + 10;
  379.       else if (*cp >= 'A' && *cp <= 'F')
  380.     val = val * 16 + *cp - 'A' + 10;
  381.       else if (*cp >= '0' && *cp <= '9')
  382.     val = val * 16 + *cp - '0';
  383.       else
  384.     break;
  385.       cp++;
  386.     }
  387.   return val;
  388. }
  389.